home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / mail / PPCuucoders.lha / PPCuucoders / uuencode.c < prev    next >
C/C++ Source or Header  |  1998-02-07  |  4KB  |  174 lines

  1.  
  2. /*
  3.  * uuencode >outfile [infile] name
  4.  *
  5.  * Encode a file so it can be mailed to a remote system.  This version
  6.  * transparantly adds line checksums and a file size for sanity checks.
  7.  *
  8.  */
  9.  
  10. /* Modified by Andreas R. Kleinert
  11.  *
  12.  * 07.02.98: - powerUP (TM) version, compiled with SAS/C for PPC
  13.  *
  14.  * 31.08.97: - reworked for SAS/C 6.58
  15.  *           - better compiler settings
  16.  *           - ANSI-fied
  17.  *
  18.  * 04.08.94: - first, internal version
  19.  *
  20.  *
  21.  * Original authors:
  22.  *
  23.  * Written by Mark Horton
  24.  * Modified by ajr (Alan J Rosenthatl,flaps@utcsri.UUCP) to use checksums
  25.  * Modified by fnf (Fred Fish,well!fnf) to use Keith Pyle's suggestion for
  26.  * compatibility
  27.  * Modified by bcn (Bryce Nesbitt,ucbvax!hoser!bryce) to enable CTRL-C for
  28.  * Amiga Lattice C.  Added a transparent file size trailer for later check.
  29.  * Changed fopen from "r" to "rb" for Messy-dos machines (thanks to Andrew
  30.  * Wylie)
  31.  */
  32.  
  33. #define __USE_SYSBASE
  34.  
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38.  
  39. #include <sys/types.h>
  40. #include <sys/stat.h>
  41.  
  42. #include <exec/types.h>
  43.  
  44. #include <proto/exec.h>
  45.  
  46.  
  47. LONG filemode(FILE *in);
  48. void encode(FILE *in, FILE *out);
  49. LONG outdec(UBYTE *p, FILE *f);
  50. LONG fr(FILE *fd, UBYTE *buf, LONG cnt);
  51.  
  52. LONG totalsize = 0; /* Used to count the file size because ftell() does
  53.                not return sane results for pipes */
  54.  
  55. UBYTE __aligned version [] = "\0$VER: uuencode 1.0 (7.2.98)";
  56.  
  57. long main(long argc, char **argv)
  58. {
  59.     FILE *in;
  60.     LONG mode;
  61.  
  62.     /* optional 1st argument */
  63.     if (argc > 2) {
  64.         if ((in = fopen(argv[1], "r")) == NULL) {
  65.             fprintf(stderr, "ERROR: can't find %s\n", argv[1]);
  66.             fprintf(stderr, "USAGE: uuencode >outfile [infile] name\n");
  67.             exit(20);
  68.         }
  69.         argv++; argc--;
  70.     } else
  71.         in = stdin;
  72.  
  73.     if (argc != 2) {
  74.         fprintf(stderr, "USAGE: uuencode >outfile [infile] name\n");
  75.         exit(0);
  76.     }
  77.  
  78.         mode = filemode(in);
  79.  
  80.     printf("\nbegin %o %s\n", mode, argv[1]);
  81.  
  82.     encode(in, stdout);
  83.  
  84.     printf("end\n");
  85.     printf("size %ld\n",totalsize);
  86.     exit(0);
  87. }
  88.  
  89. LONG filemode(FILE *in)
  90. {
  91. #ifdef unix_stat
  92.     struct stat sbuf;
  93.     
  94.     fstat(fileno(in), &sbuf);
  95.     return( sbuf.st_mode & 0777); /* figure out the input file mode */
  96.  
  97. #else
  98.     return( 0644 );               /* Default permissions */
  99. #endif
  100. }
  101.  
  102. #define SUMSIZE 64  /* 6 bits */
  103. /* ENC is the basic 1 character encode function to make a char printing */
  104. /* Each output character represents 6 bits of input */
  105. #define ENC(c) ((c) ? ((c) & 077) + ' ': '`')
  106.  
  107. /*
  108.  * copy from in to out, encoding as you go along.
  109.  */
  110. void encode(FILE *in, FILE *out)
  111. {
  112.  extern errno;
  113.  
  114.     LONG i, n, checksum;
  115.     char buf[256];
  116.  
  117.     for (;;) {
  118.         /* 1 (up to) 45 character line */
  119.         n = fr(in, buf, 45);
  120.         putc(ENC(n), out);
  121.  
  122.         checksum = 0;
  123.         for (i=0; i<n; i += 3)
  124.             checksum = (checksum+outdec(&buf[i], out)) % SUMSIZE;
  125.  
  126.         putc(ENC(checksum), out);
  127.         putc('\n', out);
  128.  
  129.         /* Error checking under UNIX?? You must be kidding! */
  130.         if (errno) {
  131.             fprintf(stderr, "ERROR: error writing to output\n");
  132.             exit(20);
  133.             }
  134.  
  135.         if (n <= 0)
  136.             break;
  137.     }
  138. }
  139.  
  140. /*
  141.  * output one group of 3 bytes, pointed at by p, on file f.
  142.  * return the checksum increment.
  143.  */
  144. LONG outdec(UBYTE *p, FILE *f)
  145. {
  146.     LONG c1, c2, c3, c4;
  147.  
  148.     c1 = *p >> 2;
  149.     c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
  150.     c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
  151.     c4 = p[2] & 077;
  152.     putc(ENC(c1), f);
  153.     putc(ENC(c2), f);
  154.     putc(ENC(c3), f);
  155.     putc(ENC(c4), f);
  156.  
  157.     return((p[0]+p[1]+p[2]) % SUMSIZE);
  158. }
  159.  
  160. /* fr: like read but stdio */
  161. LONG fr(FILE *fd, UBYTE *buf, LONG cnt)
  162. {
  163.     LONG c, i;
  164.  
  165.     for (i=0; i<cnt; i++) {
  166.         c = getc(fd);
  167.         if (c == EOF)
  168.             return(i);
  169.         totalsize++;
  170.         buf[i] = c;
  171.     }
  172.     return (cnt);
  173. }
  174.